package com.base.vistter.iframe.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.base.vistter.iframe.bean.SystemContextHolder;
import com.base.vistter.iframe.entity.InverterDevices;
import com.base.vistter.iframe.entity.InverterStation;
import com.base.vistter.iframe.exception.IframeException;
import com.base.vistter.iframe.mapper.InverterDevicesMapper;
import com.base.vistter.iframe.mapper.InverterStationMapper;
import com.base.vistter.iframe.model.DevicesElectricityOverview;
import com.base.vistter.iframe.utils.DateUtils;
import com.base.vistter.iframe.utils.StringUtils;
import com.base.vistter.iframe.utils.ToolUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class InverterDevicesService extends BaseService<InverterDevicesMapper, InverterDevices> implements Serializable {

    @Resource(name = "inverterStationMapper")
    private InverterStationMapper inverterStationMapper;

    @Resource(name = "inverterDevicesPowerMonthService")
    private InverterDevicesPowerMonthService inverterDevicesPowerMonthService;
    @Transactional(readOnly = true)
    public Page<InverterDevices> pageInverterDevices(Page<InverterDevices> page , Integer stationId, Integer status) throws IframeException {
        Long total = this.baseMapper.pageInverterDevicesCount(DateUtils.getTodayStartTime() ,DateUtils.getTodayEndTime(), stationId ,status);
        if(total == 0L){
            return page;
        }
        page.setTotal(total);
        page.setRecords(this.baseMapper.pageInverterDevicesList(DateUtils.getTodayStartTime() ,DateUtils.getTodayEndTime(), stationId ,status));
        return page;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public boolean save(InverterDevices entity) throws IframeException {
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(entity.getNo())) {
            LambdaQueryWrapper<InverterDevices> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(InverterDevices::getNo, entity.getNo());
            if (super.exists(lambdaQueryWrapper)) {
                throw new IframeException("设备编号已存在");
            }
        } else {
            String no = generateNo();
            boolean isExit = true;
            while (isExit){
                isExit = isExitByNo(no);
                if(isExit){
                    no = generateNo();
                }
            }
            entity.setNo(no);
        }
        return super.save(entity);
    }

    public boolean isExitByNo(String no) throws IframeException{
        LambdaQueryWrapper<InverterDevices> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(InverterDevices::getNo, no);
        return exists(lambdaQueryWrapper);
    }

    public String generateNo() {
        return StringUtils.generateRandomString(8);
    }

    @Transactional(readOnly = true)
    public List<Integer> getDevicesIds(Integer inverterStationId) throws IframeException{
        LambdaQueryWrapper<InverterDevices> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(InverterDevices::getInverterStationId , inverterStationId);
        List<InverterDevices> list = super.selectList(lambdaQueryWrapper);
        return list.stream().map(InverterDevices::getId).collect(Collectors.toList());
    }

    public List<InverterDevices> getMyDevices() throws IframeException{
        List<InverterStation> list = inverterStationMapper.myStation(SystemContextHolder.getSessionContext().getUserId());
        if(list == null || list.isEmpty()){
            return null;
        }
        List<Integer> stationIds = list.stream().map(InverterStation::getId).toList();
        LambdaQueryWrapper<InverterDevices> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(InverterDevices::getInverterStationId , stationIds);
        return super.selectList(lambdaQueryWrapper);
    }

    @Transactional(readOnly = true)
    public List<Map<String, Object>> countStatus(Integer stationId) throws IframeException {
        QueryWrapper<InverterDevices> queryWrapper = Wrappers.query();
        queryWrapper.select("status", "count(*) as counting").eq("inverter_station_id" , stationId).groupBy("status");
        return super.selectMaps(queryWrapper);
    }

    @Transactional(readOnly = true)
    public DevicesElectricityOverview getDevicesElectricity(Integer devicesId) throws IframeException {
        Date now = new Date();
        Long totalMonthElectricity = inverterDevicesPowerMonthService.getDevicesPower(devicesId, DateUtils.getMonthStartTime(now), DateUtils.getMonthEndTime(now));
        Long totalYearElectricity = inverterDevicesPowerMonthService.getDevicesPower(devicesId, DateUtils.getYearStartTime(now),  DateUtils.getYearEndTime(now));
        return new DevicesElectricityOverview(totalMonthElectricity, totalYearElectricity);
    }

}
